package com.cssy.xxkj.logic.service.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONArray;
import com.byd.acegiext.domain.User;
import com.cssy.xxkj.logic.contants.BillStatusUtil;
import com.cssy.xxkj.logic.contants.BillTypeConstant;
import com.cssy.xxkj.logic.dao.LogicPurchaseDAO;
import com.cssy.xxkj.logic.dao.LogicPurchaseItemDAO;
import com.cssy.xxkj.logic.dao.LogicPurchaseWareDAO;
import com.cssy.xxkj.logic.dao.LogicPurchaseWareItemDAO;
import com.cssy.xxkj.logic.entity.LogicPurchaseDO;
import com.cssy.xxkj.logic.entity.LogicPurchaseItemDO;
import com.cssy.xxkj.logic.entity.LogicPurchaseWareDO;
import com.cssy.xxkj.logic.entity.LogicPurchaseWareItemDO;
import com.cssy.xxkj.logic.service.ILogicHsUtilService;
import com.cssy.xxkj.logic.service.ILogicPurchaseWareService;
import com.plat.exception.SyBaseException;
import com.plat.helper.SearchConditions;
import com.plat.helper.SearchResult;
import com.plat.util.DateUtils;
import com.plat.util.GlobalResLoader;
import com.plat.util.IDCodeTypeUtil;
import com.plat.util.SessionUtil;
import com.yuendong.sy.po.code.SyCode;
import com.yuendong.sy.service.code.impl.SyCodeService;

@Service("logicPurchaseWareService")
public class LogicPurchaseWareServiceImpl implements ILogicPurchaseWareService {
	
	@Resource(name = "logicPurchaseDAO")
	private LogicPurchaseDAO logicPurchaseDAO;
	
	@Resource(name = "logicPurchaseItemDAO")
	private LogicPurchaseItemDAO logicPurchaseItemDAO;

	@Resource(name = "logicPurchaseWareDAO")
	private LogicPurchaseWareDAO logicPurchaseWareDAO;
	
	@Resource(name = "logicPurchaseWareItemDAO")
	private LogicPurchaseWareItemDAO logicPurchaseWareItemDAO;
	
	@Resource(name = "logicHsUtilService")
	private ILogicHsUtilService logicHsUtilService;
	
	@Resource(name = "syCodeService")
	private SyCodeService syCodeService;
	
	@Override
	public SearchResult findListByExample(SearchConditions scs)
			throws SyBaseException {
		SearchResult rs=new SearchResult(scs);
		List<LogicPurchaseWareDO> list = logicPurchaseWareDAO.find(scs);
		rs.setRecordCount(logicPurchaseWareDAO.count(scs));
		rs.setResults(list);
		return rs;
	}
	
	@Override
	public List<LogicPurchaseWareItemDO> findItemListByMap(Map<String, Object> paramMap)
			throws DataAccessException{
		return logicPurchaseWareItemDAO.findListByMap(paramMap);
	}

	@Override
	public Integer delete(String id, User user) throws SyBaseException {
		return logicPurchaseWareDAO.deleteLogicPurchaseWareDOByPrimaryKey(id);
	}

	@Override
	public Integer update(LogicPurchaseWareDO purchaseWare, User user)
			throws SyBaseException {
		purchaseWare.setBizModifyName(user.getName());
		purchaseWare.setBizModifyDate(new Date());
		purchaseWare.setBizVersionMark(purchaseWare.getBizVersion());
		purchaseWare.setBizVersion(purchaseWare.getBizVersion()+Integer.valueOf(1));
		return logicPurchaseWareDAO.updateLogicPurchaseWareDO(purchaseWare);
	}

	@Override
	public LogicPurchaseWareDO save(LogicPurchaseWareDO pcsWare, User user)
			throws SyBaseException {
		if(StringUtils.isBlank(pcsWare.getBizCreatorName())){
			pcsWare.setBizCreatorName(user.getName());
		}
		pcsWare.setBizCreatorDate(new Date());
		logicPurchaseWareDAO.insertLogicPurchaseWareDO(pcsWare);
		return pcsWare;
	}
	
	@Override
	public void purchaseWareSave(HttpServletRequest request,
			LogicPurchaseWareDO curAP)throws SyBaseException{
		String itemdata = request.getParameter("itemdata");//新增数据
		String itemdatadel = request.getParameter("itemdelete");//删除数据
		String flagMark = request.getParameter("flagMark");
		//入库日期
		String zd013Date = request.getParameter("zd013Date");
		if(StringUtils.isBlank(zd013Date)){
			curAP.setZd013Date(null);
		}else{
			curAP.setZd013Date(DateUtils.stringToDate(zd013Date));
		}
		SearchConditions scs= new SearchConditions();
		scs.addCondition("id", curAP.getId());
		List<LogicPurchaseWareDO> listPD=logicPurchaseWareDAO.find(scs);
		LogicPurchaseWareDO pcsWareDO=new LogicPurchaseWareDO();
		if(listPD.size()==1){
			pcsWareDO=listPD.get(0);
		}else{
			pcsWareDO=null;
		}
//		LogicPurchaseWareDO pcsWareDO = logicPurchaseWareDAO.findLogicPurchaseWareDOByPrimaryKey(curAP.getId());
		try{
			if(BillStatusUtil.PCSW_BILL_STATUS_FIVE.equals(flagMark)){
				//驳回
				if(pcsWareDO==null){
					throw new SyBaseException("您修改的行数据发生改变，请重新点开查看");
				}
				pcsWareDO.setZd004Status(BillStatusUtil.PCSW_BILL_STATUS_FIVE);
				this.update(pcsWareDO, SessionUtil.getUser(request));
			}else{
				//采购入库单的付款状态默认未：未付款
				curAP.setZd004PayStatus(BillStatusUtil.PCSW_PAY_BILL_STATUS_ONE);
				List<LogicPurchaseWareItemDO> pcswmList = JSONArray.parseArray(itemdata,LogicPurchaseWareItemDO.class);
				if(curAP==null || StringUtils.isBlank(curAP.getId())){
					//新增
					String pcswId = IDCodeTypeUtil.getId();
					curAP.setId(pcswId);
					curAP.setZd003Code(syCodeService.getCode(BillTypeConstant.PURCHASEWARE,BillTypeConstant.PURCHASEWARE,SyCode.DATE_YYMM,5));
					curAP.setBizVersion(Integer.valueOf(1));
					curAP.setZd004Status(flagMark);
					this.save(curAP, SessionUtil.getUser(request));
					//增加行记录
					this.pcswItemAddOrUp(pcswmList, pcswId, false);
				}else{
					if(pcsWareDO==null){
						throw new SyBaseException("您修改的行数据发生改变，请重新点开查看");
					}
					if(BillStatusUtil.PCSW_BILL_STATUS_FOUR.equals(flagMark)){
						LogicPurchaseWareDO pcsw = logicPurchaseWareDAO.findLogicPurchaseWareDOByPrimaryKey(curAP.getId());
						if(pcsw==null){
							throw new SyBaseException("数据发生改变，请重新提交");
						}
						//修改库存
						String pcsId = pcsw.getZd001PcsId();
						Map<String, BigDecimal> hasInMap = this.findQueryPcsItem(pcsId);
						LogicPurchaseDO pcs = logicPurchaseDAO.findLogicPurchaseDOByPrimaryKey(pcsId);
						Map<String, LogicPurchaseItemDO> pcsmItemMap = this.findQueryPcsmToMap(pcsId);
						for(LogicPurchaseWareItemDO pcswmItem : pcswmList){
							if(pcswmItem==null){
								continue;
							}
							String keyStr = pcsId+"_"+pcswmItem.getZd003MaterId()+"_"+pcswmItem.getZd007Model()+"_"
									+pcswmItem.getZd011Size()+"_"+pcswmItem.getZd009Color()+"_"
									+pcswmItem.getZd010Quality();
							//总数
							BigDecimal sumInQuantity = pcswmItem.getZd014Quatity()==null?BigDecimal.ZERO:pcswmItem.getZd014Quatity();
							//本次入库数量
							BigDecimal theQuantity = pcswmItem.getZd018HsQuantity()==null?BigDecimal.ZERO:pcswmItem.getZd018HsQuantity();
							//已入库数量
							BigDecimal hasInQuantity = BigDecimal.ZERO;
							if(hasInMap==null || hasInMap.get(keyStr)==null){
								hasInQuantity = BigDecimal.ZERO;
							}else{
								hasInQuantity = hasInMap.get(keyStr);
							}
							//总数-(已入库数量+本次入库数量)
							BigDecimal comQuantity = sumInQuantity.subtract(hasInQuantity.add(theQuantity));
							int rowComp = BigDecimal.ZERO.compareTo(comQuantity);
							if(rowComp==1){
								throw new SyBaseException("入库数量已大于采购订单数量。");
							}else{
								LogicPurchaseItemDO pcsm = pcsmItemMap.get(keyStr);
								if(pcsm==null){
									throw new SyBaseException("没有找到物料："+pcswmItem.getZd005Name()+"请核对。");
								}else{
									//已入库数量
									BigDecimal zdHostQuantity = pcsm.getZd018HostQuatity()==null?BigDecimal.ZERO:pcsm.getZd018HostQuatity();
									pcsm.setZd018HostQuatity(theQuantity.add(zdHostQuantity));
									//更新map中的pcsm的新值
									pcsmItemMap.put(keyStr, pcsm);
									this.logicPurchaseItemDAO.updateLogicPurchaseItemDO(pcsm);
								}
							}
							//修改库存
							logicHsUtilService.processHsPurchaseWareItem(curAP, pcswmItem, SessionUtil.getUser(request));
						}
						boolean upSt = true;
						for(LogicPurchaseItemDO pcsItem : pcsmItemMap.values()){
							if(pcsItem==null){
								continue;
							}
							BigDecimal inQuantity = pcsItem.getZd011Quatity()==null?BigDecimal.ZERO:pcsItem.getZd011Quatity();
							BigDecimal hasQuantity = pcsItem.getZd018HostQuatity()==null?BigDecimal.ZERO:pcsItem.getZd018HostQuatity();
							BigDecimal upQuantity = inQuantity.subtract(hasQuantity);
							int canUpSt = BigDecimal.ZERO.compareTo(upQuantity);
							if(canUpSt==-1){
								upSt = false;
							}
						}
						if(upSt){
							pcs.setZd011WhStatus(BillStatusUtil.PCSWH_BILL_STATUS_TWO);
						}else{
							pcs.setZd011WhStatus(BillStatusUtil.PCSWH_BILL_STATUS_ONE);
						}
						pcs.setBizVersionMark(pcs.getBizVersion());
						logicPurchaseDAO.updateLogicPurchaseDO(pcs);
						//处理当前的记录
						pcsw.setZd004Status(flagMark);
						if(StringUtils.isNotBlank(zd013Date)){
							pcsw.setZd013Date(DateUtils.stringToDate(zd013Date));
						}
						Integer rowUp = this.update(pcsw, SessionUtil.getUser(request));
						if(rowUp==null || rowUp.intValue()==0){
							throw new SyBaseException("数据发生改变，请重新提交。");
						}
						//处理删除的
						this.pcswItemToRemove(itemdatadel);
					}else{
						curAP.setZd004Status(flagMark);
						Integer rowUp = this.update(curAP, SessionUtil.getUser(request));
						if(rowUp==null || rowUp.intValue()==0){
							throw new SyBaseException("数据发生改变，请重新提交。");
						}else{
							//删除的行记录信息
							this.pcswItemToRemove(itemdatadel);
							//增加行记录
							this.pcswItemAddOrUp(pcswmList, curAP.getId(), true);
						}
					}
				}
			}
		}catch(Exception e){
			e.printStackTrace();
			throw new SyBaseException(GlobalResLoader.getOpfailed()+ e.getMessage());
		}
	}
	
	/**
	 * 删除采购入库单的行记录
	 * @param pcswRelStr
	 * @throws SyBaseException
	 */
	private void pcswItemToRemove(String pcswRelStr)throws SyBaseException{
		if(StringUtils.isNotBlank(pcswRelStr)){
			List<LogicPurchaseWareItemDO> pcswmList = JSONArray.parseArray(pcswRelStr,LogicPurchaseWareItemDO.class);
			for(LogicPurchaseWareItemDO pcswm : pcswmList){
				if(pcswm==null || StringUtils.isBlank(pcswm.getId())){
					continue;
				}
				logicPurchaseWareItemDAO.deleteLogicPurchaseWareItemDOByPrimaryKey(pcswm.getId());
			}
		}
	}
	
	/**
	 * 新增或者删除采购入库的行记录信息
	 * @param pcswmList
	 * @param pcswId
	 * @param addOrUp
	 * @throws SyBaseException
	 */
	private void pcswItemAddOrUp(List<LogicPurchaseWareItemDO> pcswmList, String pcswId, boolean addOrUp)throws SyBaseException{
		if(addOrUp){
			for(LogicPurchaseWareItemDO pcswm : pcswmList){
				if(pcswm==null){
					continue;
				}else{
					if(StringUtils.isNotBlank(pcswm.getId())){
						logicPurchaseWareItemDAO.updateLogicPurchaseWareItemDO(pcswm);
					}else{
						pcswm.setId(IDCodeTypeUtil.getId());
						pcswm.setZd001PusWareId(pcswId);
						logicPurchaseWareItemDAO.insertLogicPurchaseWareItemDO(pcswm);
					}
				}
			}
		}else{
			for(LogicPurchaseWareItemDO pcswm : pcswmList){
				if(pcswm==null){
					continue;
				}
				pcswm.setId(IDCodeTypeUtil.getId());
				pcswm.setZd001PusWareId(pcswId);
				logicPurchaseWareItemDAO.insertLogicPurchaseWareItemDO(pcswm);
			}
		}
	}
	
	//根据当前的采购入库单的采购订单id，查询所有的已入库的采购订单
	private Map<String, BigDecimal> findQueryPcsItem(String pcsId){
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("pcsId", pcsId);
		paramMap.put("zdStatus", BillStatusUtil.PCSW_BILL_STATUS_FOUR);
		List<LogicPurchaseWareItemDO> pcswmList = logicPurchaseWareItemDAO.findListByMap(paramMap);
		if(pcswmList==null||pcswmList.isEmpty()||pcswmList.size()==0){
			return null;
		}else{
			Map<String, BigDecimal> pcswmMap = new HashMap<String, BigDecimal>();
			for(LogicPurchaseWareItemDO pcswm : pcswmList){
				if(pcswm==null){
					continue;
				}
				String keyStr = pcsId+"_"+pcswm.getZd003MaterId()+"_"
					+pcswm.getZd007Model()+"_"+pcswm.getZd011Size()+"_"
					+pcswm.getZd009Color()+"_"+pcswm.getZd010Quality();
				//每次入库数量
				BigDecimal inQuantity = pcswm.getZd018HsQuantity()==null?BigDecimal.ZERO:pcswm.getZd018HsQuantity();
				if(pcswmMap.get(keyStr)==null){
					pcswmMap.put(keyStr, inQuantity);
				}else{
					pcswmMap.put(keyStr, inQuantity.add(pcswmMap.get(keyStr)));
				}
			}
			return pcswmMap;
		}
		
	}
	
	private Map<String, LogicPurchaseItemDO> findQueryPcsmToMap(String pcsId){
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("pcsId", pcsId);
		List<LogicPurchaseItemDO> pcsmList =logicPurchaseItemDAO.findListByMap(paramMap);
		if(pcsmList==null||pcsmList.isEmpty()||pcsmList.size()==0){
			return null;
		}else{
			Map<String, LogicPurchaseItemDO> pcsmMap = new HashMap<String, LogicPurchaseItemDO>();
			for(LogicPurchaseItemDO pcsm : pcsmList){
				if(pcsm==null){
					continue;
				}
				String keyStr = pcsId + "_" + pcsm.getZd002MaterId()+"_"
						+pcsm.getZd006Model()+"_"+pcsm.getZd023Size()+"_"
						+pcsm.getZd021Color()+"_"+pcsm.getZd022Quality();
				pcsmMap.put(keyStr, pcsm);
			}
			return pcsmMap;
		}
	}
	
	@Override
	public LogicPurchaseWareDO findListById(String id) throws SyBaseException {
		return logicPurchaseWareDAO.findLogicPurchaseWareDOByPrimaryKey(id);
	}

	@Override
	public Integer deleteBizRemoved(String id) throws SyBaseException {
		return logicPurchaseWareDAO.deleteBizRemoved(id);
	}
	
}
